package han.parser;

import han.entity.GroupEntity;
import han.entity.GroupMemberEntity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.*;

/**
 * @author: Han
 * @date: 2018/7/10 9:20
 * @dscription: 群组解析正则表达式
 */
public class GroupParser {
    /**
     * 解析出群组名称list
     *
     * @param jsonStr 群组原始字符串
     * @return 群组list
     */
    public static List<GroupEntity> getGroupNameFromSmartqq(String jsonStr) {

        List<GroupEntity> entityList = new ArrayList<>();
        JSONObject rowJsonObj = new JSONObject(jsonStr);
        JSONObject resultJsonObj = rowJsonObj.getJSONObject("result");
        JSONArray nameListArray = resultJsonObj.getJSONArray("gnamelist");
        //遍历json数组
        for (int i = 0; i < nameListArray.length(); i++) {
            JSONObject tempJsonObj = nameListArray.getJSONObject(i);
            long flag = tempJsonObj.getLong("flag");
            String name = tempJsonObj.getString("name");
            long gid = tempJsonObj.getLong("gid");
            long code = tempJsonObj.getLong("code");
            GroupEntity entity = new GroupEntity();
            entity.setFlag(flag);
            entity.setName(name);
            entity.setGid(gid);
            entity.setCode(code);
            entityList.add(entity);
        }

        return entityList;
    }

    /**
     * 解析群详细信息
     *
     * @param jsonStr 原始字符串
     * @return 群详细信息
     */
    public static Map<String, GroupMemberEntity> getGroupMemberMapFromSmartqq(String jsonStr) {
        JSONObject resultJsonStr = new JSONObject(jsonStr).getJSONObject("result");

        //群成员信息
        Map<String, GroupMemberEntity> memberMap = new HashMap<>(10);
        JSONArray minfoArray = resultJsonStr.getJSONArray("minfo");
        for (int i = 0; i < minfoArray.length(); i++) {
            JSONObject tempJsonObj = minfoArray.getJSONObject(i);
            String nick = tempJsonObj.getString("nick");
            String province = tempJsonObj.getString("province");
            String gender = tempJsonObj.getString("gender");
            long uin = tempJsonObj.getLong("uin");
            String country = tempJsonObj.getString("country");
            String city = tempJsonObj.getString("city");
            //检测是否有昵称重复的,如果有在昵称后面加个.
            if (memberMap.containsKey(nick)) {
                nick += ".";
            }
            GroupMemberEntity entity = new GroupMemberEntity();
            entity.setNickName(nick);
            entity.setProvince(province);
            entity.setCity(city);
            entity.setCountry(country);
            entity.setGender(gender);
            entity.setUin(uin);
            memberMap.put(nick, entity);
        }
        return memberMap;
    }

    /**
     * 通过QQ群官网获取QQ群名,群主QQ号,群号
     *
     * @param jsonStr 获取到的我字符串
     * @return 群列表
     */
    public static List<GroupEntity> getGroupListFromGroupWebsite(String jsonStr) {

        List<GroupEntity> groupList = new ArrayList<>();

        JSONObject rowJsonObj = new JSONObject(jsonStr);
        //自己创建的QQ群
        try {
            JSONArray createArray = rowJsonObj.getJSONArray("create");
            List<GroupEntity> createList = getGroupListByJsonArrayFromWebsite(createArray);
            groupList.addAll(createList);
        } catch (JSONException ignore) {
        }

        //加入的QQ群
        try {
            JSONArray joinArray = rowJsonObj.getJSONArray("join");
            List<GroupEntity> joinList = getGroupListByJsonArrayFromWebsite(joinArray);
            groupList.addAll(joinList);
        } catch (JSONException ignore) {
        }

        //加入的QQ群
        try {
            JSONArray manageArray = rowJsonObj.getJSONArray("manage");
            List<GroupEntity> manageList = getGroupListByJsonArrayFromWebsite(manageArray);
            groupList.addAll(manageList);
        } catch (JSONException ignore) {
        }

        return groupList;
    }

    /**
     * 从json数组中解析出群信息
     *
     * @param array json数组
     * @return 群信息
     */
    private static List<GroupEntity> getGroupListByJsonArrayFromWebsite(JSONArray array) {
        List<GroupEntity> groupList = new ArrayList<>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject tempObj = array.getJSONObject(i);
            long groupAccount = tempObj.getLong("gc");
            String name = tempObj.getString("gn");
            long ownerAccount = tempObj.getLong("owner");
            GroupEntity entity = new GroupEntity();
            entity.setGroupAccount(groupAccount);
            entity.setName(name);
            entity.setOwnerAccount(ownerAccount);
            groupList.add(entity);
        }

        return groupList;
    }

    /**
     * 解析群成员,并放入map,key:昵称,value:群成员实体
     *
     * @param jsonStr json字符串
     * @return map
     */
    public static Map<String, GroupMemberEntity> getGroupMemberMapFromWebsite(String jsonStr) {

        Map<String, GroupMemberEntity> memberMap = new HashMap<>(10);
        JSONArray array = new JSONObject(jsonStr).getJSONArray("mems");
        for (int i = 0; i < array.length(); i++) {
            //解析出昵称和QQ号
            JSONObject tempObj = array.getJSONObject(i);
            long account = tempObj.getLong("uin");
            String nick = tempObj.getString("nick");
            //检测是否有昵称重复的,如果有在昵称后面加个.
            if (memberMap.containsKey(nick)) {
                nick += ".";
            }
            GroupMemberEntity entity = new GroupMemberEntity();
            entity.setNickName(nick);
            entity.setAccount(account);
            memberMap.put(nick, entity);
        }

        return memberMap;
    }

    public static Map<String, GroupEntity> fuseGroupList(List<GroupEntity> websiteGroupList, List<GroupEntity>
            smartqqGroupList) {

        Map<String, GroupEntity> fusedGroupMap = new HashMap<>(10);

        Random random = new Random();
        for (GroupEntity smartqqGroup : smartqqGroupList) {
            //官网群名
            String smartqqGroupName = smartqqGroup.getName();
            //官网成员列表
            Map<String, GroupMemberEntity> smartqqMemberMap = smartqqGroup.getMemberMap();
            for (GroupEntity websiteGroup : websiteGroupList) {
                //smartqq群名
                String websiteGroupName = websiteGroup.getName();
                //smartqq成员列表
                Map<String, GroupMemberEntity> websiteMemberMap = websiteGroup.getMemberMap();
                boolean nameSame = websiteGroupName.equals(smartqqGroupName);
                //群名相同,且群人数差在10人之内(考虑到分别从QQ群官网和smartQQ获取的群信息间隔中,可能会新加入或者退出群成员)
                if (nameSame) {
                    List<String> websiteMemberNameList = new ArrayList<>(new TreeSet<>(websiteMemberMap.keySet()));
                    List<String> smartqqMemberNameList = new ArrayList<>(new TreeSet<>(smartqqMemberMap.keySet()));
                    int successCount = 0;
                    //随机取出randomCount个名字,只要有80%以上相同,即视为两个群是一个群
                    int randomCount;
                    int memberCount = websiteMemberNameList.size();
                    if (memberCount <= 50) {
                        randomCount = 10;
                    } else if (memberCount < 100) {
                        randomCount = (int) (memberCount * 0.2);
                    } else if (memberCount < 500) {
                        randomCount = (int) (memberCount * 0.1);
                    } else {
                        randomCount = 50;
                    }
                    for (int loop = 0; loop < randomCount; loop++) {
                        int index = random.nextInt(websiteMemberNameList.size());
                        String websiteName = websiteMemberNameList.get(index);
                        boolean tempContain = smartqqMemberNameList.contains(websiteName);
                        if (tempContain) {
                            successCount++;
                        }
                    }
                    //如果不相同,则继续下一个
                    boolean isContinue = (double) successCount / (double) randomCount < 0.8;
                    if (isContinue) {
                        continue;
                    }
                    //设置群号和群主QQ号
                    long groupAccount = websiteGroup.getGroupAccount();
                    long ownerAccount = websiteGroup.getOwnerAccount();
                    smartqqGroup.setGroupAccount(groupAccount);
                    smartqqGroup.setOwnerAccount(ownerAccount);
                    //如果两个群为同一个群,融合群成员列表
                    //选择人多的列表
                    List<String> memberNameList = websiteMemberMap.size() < smartqqMemberMap.size() ?
                            websiteMemberNameList : smartqqMemberNameList;
                    Map<String, GroupMemberEntity> newMemberMap = new HashMap<>(10);
                    for (String memberName : memberNameList) {
                        GroupMemberEntity websiteMember = websiteMemberMap.get(memberName);
                        GroupMemberEntity smartqqMember = smartqqMemberMap.get(memberName);
                        if (Objects.isNull(smartqqMember)) {
                            //如果smartqq获取的成员为空,说明不会在接收到该成员信息,直接下一位
                            continue;
                        }
                        if (Objects.isNull(websiteMember)) {
                            //如果QQ群官网获取的为空,到时候只能不显示QQ号了
                            newMemberMap.put(smartqqMember.getUin() + "", smartqqMember);
                            continue;
                        }
                        //获取QQ号
                        long account = websiteMember.getAccount();
                        smartqqMember.setAccount(account);
                        //设置新的
                        newMemberMap.put(smartqqMember.getUin() + "", smartqqMember);
                    }
                    //设置融合后的map
                    smartqqGroup.setMemberMap(newMemberMap);
                    //放入新的容器中
                    fusedGroupMap.put(smartqqGroup.getGid() + "", smartqqGroup);
                    //移除已经匹配到的QQ群,并且跳出
                    websiteGroupList.remove(websiteGroup);
                    break;
                }
            }
        }

        return fusedGroupMap;
    }
}
